﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace WssUtils
{

    public static class MathTool
    {
        /// <summary>
        /// 将[xMin，xMax]区间上的数映射到区间[yMin,yMax]上
        /// </summary>
        /// <param name="mathf"></param>
        /// <param name="x"></param>
        /// <param name="xMin"></param>
        /// <param name="xMax"></param>
        /// <param name="yMin"></param>
        /// <param name="yMax"></param>
        /// <returns></returns>
        public static float Map(float x, float xMin, float xMax, float yMin, float yMax)
        {
            return (yMax - yMin) * (x - xMin) / (xMax - xMin) + yMin;
        }

        public static int Map(int x, int xMin, int xMax, int yMin, int yMax)
        {
            return Mathf.RoundToInt(Map(x, xMin, xMax, yMin, yMax));
        }

        public static double Lerp(double a, double b, double t)
        {
            if (t > 1)
            {
                t = 0;
            }
            else if (t < 0)
            {
                t = 0;
            }
            return a + t * (b - a);
        }


        /// <summary>
        /// 获取接近 2 的平方的值
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int GetNextPowerOfTwo(int value)
        {
            if (value > 0 && (value & (value - 1)) == 0)
            {
                //  http://goo.gl/D9kPj
                return value;
            }
            else
            {
                var result = 1;

                while (result < value)
                {
                    result <<= 1;
                }

                return result;
            }

        }

        /// <summary>
        /// 将正负数值 映射 到正区间，[0,1]是缩小， [1,+∞]是放大
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static float MapScaler(float value)
        {
            float speed = 0;
            if (value > 0)
            {
                speed = 1 + value;
            }
            else
            {
                speed = 1 / (1 + Mathf.Abs(value));
            }
            return speed;
        }

        public static float SnapTo(float input, float gap, float start = 0)
        {
            if (gap == 0)
            {
                return input;
            }

            input -= start;
            input = gap * Mathf.Round(input / gap);

            return start + input;
        }

        public static float SnapToFloor(float input, float gap, float start = 0)
        {
            if (gap == 0)
            {
                return input;
            }

            input -= start;
            input = gap * Mathf.Floor(input / gap);
            return start + input;

        }

        public static float SnapToCeil(float input, float gap, float start = 0)
        {
            if (gap == 0)
            {
                return input;
            }

            input -= start;
            input = gap * Mathf.Ceil(input / gap);
            return start + input;

        }


        /// <summary>
        /// 包装值，值超出边界就从另外一边出来
        /// </summary>
        /// <param name="value"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        public static int Wrap(int value, int min, int max)
        {
            var range = max - min;
            if (range <= 0)
            {
                return 0;
            }

            var result = (value - min) % range;

            if (result < 0)
            {
                result += range;
            }

            return result + min;

        }


        public static float Percent(float a, float b, float start = 0)
        {

            if (a > b || start > b)
            {
                return 1;
            }
            else if (a < start || start > a)
            {
                return 0;
            }
            else
            {
                return (a - start) / b;
            }

        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="arr"></param>
        /// <returns></returns>
        public static float Average(float[] arr)
        {
            float sum = 0;
            var len = arr.Length;
            for (int i = 0; i < len; i++)
            {
                sum += arr[i];
            }
            return sum / len;
        }

        public static int Average(int[] arr)
        {
            int sum = 0;
            var len = arr.Length;
            for (int i = 0; i < len; i++)
            {
                sum += arr[i];
            }
            return sum / len;
        }






    }

}